# -*- coding: utf-8 -*-
#
# The Philatelist program is a fork of the OpenNumismat program
# Copyright (c) 2011 - 2024 Vitaly Ignatov (OpenNumismat) <opennumismat@gmail.com>
# Copyright (c) 2021 - 2024 Victor Nabatov (Philatelist) <nabatov.victor@gmail.com>
#

from PySide6.QtCore import QObject
from PySide6.QtSql import QSqlQuery

from Philatelist.Collection.CollectionFields import CollectionFields
from Philatelist.Collection.ListPageParam import ListPageParam
from Philatelist.Collection.TreeParam import TreeParam
from Philatelist.Collection.StatisticsParam import StatisticsParam


class CollectionPageTypes:

    Default = 0
    TypeMask = 0x0F
    List = 0
    Icon = 1
    Card = 2
    InfoTypeMask = 0xF0
    Details = 0
    Statistics = 0x10


class CollectionPageParam(QObject):

    def __init__(self, record, parent=None):
        super().__init__(parent)
        for name in ('id', 'title', 'isopen'):
            setattr(self, name, record.value(name))

        setattr(
            self, 
            'type',
            record.value('type') & CollectionPageTypes.TypeMask
        )
        info_type = record.value('type') & CollectionPageTypes.InfoTypeMask
        setattr(self, 'info_type', info_type)


class CollectionPages(QObject):

    def __init__(self, db, parent=None):
        super().__init__(parent)
        self.db = db
        sql = "CREATE TABLE IF NOT EXISTS pages (\
            id INTEGER PRIMARY KEY,\
            title CHAR,\
            isopen INTEGER,\
            position INTEGER,\
            type INTEGER)"
        QSqlQuery(sql, self.db)

        self.fields = CollectionFields(self.db)
        self.params = None

    def pagesParam(self):
        if self.params is None:
            query = QSqlQuery("SELECT * FROM pages ORDER BY position")
            self.params = self.__queryToParam(query)

        return self.params

    def addPage(self, title):
        query = QSqlQuery(self.db)
        query.prepare(
            "INSERT INTO pages (title, isopen, type, position) "
            "VALUES (?, ?, ?, (SELECT COUNT(*) FROM pages))"
        )
        query.addBindValue(title)
        query.addBindValue(int(True))
        query.addBindValue(CollectionPageTypes.Default)
        query.exec_()

        query = QSqlQuery("SELECT * FROM pages WHERE id=last_insert_rowid()", self.db)
        return self.__queryToParam(query)[0]  # get only one item

    def renamePage(self, page, title):
        query = QSqlQuery(self.db)
        query.prepare("UPDATE pages SET title=? WHERE id=?")
        query.addBindValue(title)
        query.addBindValue(page.id)
        query.exec_()

    def closePage(self, page):
        query = QSqlQuery(self.db)
        query.prepare("UPDATE pages SET isopen=? WHERE id=?")
        query.addBindValue(int(False))
        query.addBindValue(page.id)
        query.exec_()

    def openPage(self, page):
        query = QSqlQuery(self.db)
        query.prepare("UPDATE pages SET isopen=? WHERE id=?")
        query.addBindValue(int(True))
        query.addBindValue(page.id)
        query.exec_()

    def removePage(self, page):
        page.listParam.remove()
        page.treeParam.remove()
        page.statisticsParam.remove()

        query = QSqlQuery(self.db)
        query.prepare("DELETE FROM pages WHERE id=?")
        query.addBindValue(page.id)
        query.exec_()

    def savePositions(self, pages):
        for position, page in enumerate(pages):
            query = QSqlQuery(self.db)
            query.prepare("UPDATE pages SET position=? WHERE id=?")
            query.addBindValue(position)
            query.addBindValue(page.id)
            query.exec_()

    def closedPages(self):
        query = QSqlQuery(self.db)
        query.prepare("SELECT * FROM pages WHERE isopen=? ORDER BY title")
        query.addBindValue(int(False))
        query.exec_()
        return self.__queryToParam(query)

    def changeView(self, page, type_):
        query = QSqlQuery(self.db)
        query.prepare("UPDATE pages SET type=? WHERE id=?")
        query.addBindValue(type_ | page.info_type)
        query.addBindValue(page.id)
        query.exec_()

    def changeInfoType(self, page, info_type):
        query = QSqlQuery(self.db)
        query.prepare("UPDATE pages SET type=? WHERE id=?")
        query.addBindValue(info_type | page.type)
        query.addBindValue(page.id)
        query.exec_()

    def __queryToParam(self, query):
        pagesParam = []
        while query.next():
            param = CollectionPageParam(query.record())
            param.fields = self.fields
            param.db = self.db
            # TODO: Improve code
            if param.type == CollectionPageTypes.List:
                param.listParam = ListPageParam(param)

            elif param.type == CollectionPageTypes.Icon:
                param.listParam = ListPageParam(param)

            param.treeParam = TreeParam(param)
            param.statisticsParam = StatisticsParam(param)
            pagesParam.append(param)

        return pagesParam
